// --------------------------------------------------------------------------------------------------------------------
// <copyright file="WeakKeyHashMap.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   WeakKeyHashMap
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Collections
{
    using System;

    public class WeakKeyHashMap<TKey, TValue> : HashMap<TKey, TValue> where TKey : class
    {
        #region WeakKeyHashMapEntry

        protected class WeakKeyHashMapEntry : Entry
        {
            private readonly WeakReference _keyReference;
            private TValue _value;

            /// <summary>
            /// Initializes a new instance of the <see cref="WeakKeyHashMap&lt;TKey, TValue&gt;.WeakKeyHashMapEntry"/> class.
            /// </summary>
            /// <param name="key">The key.</param>
            /// <param name="value">The value.</param>
            public WeakKeyHashMapEntry(TKey key, TValue value)
            {
                // Allocate a weak handle for the key 
                _keyReference = new WeakReference(key);
                _value = value;
            }

            /// <summary>
            /// Gets the key for the entry.
            /// </summary>
            public override TKey Key
            {
                get
                {
                    return (TKey)_keyReference.Target;
                }
            }

            /// <summary>
            /// Gets or sets the value contained by the entry.
            /// </summary>
            /// <remarks>
            /// The value is tracked via a weak reference.
            /// </remarks>
            public override TValue Value
            {
                get
                {
                    return _value;
                }
                set
                {
                    _value = value;
                }
            }

            /// <summary>
            /// Gets a value indicating whether this instance is alive.
            /// </summary>
            /// <value><c>true</c> if this instance is alive; otherwise, <c>false</c>.</value>
            public override bool IsAlive
            {
                get { return _keyReference.IsAlive; }
            }
        }

        #endregion

        protected override void OnResize()
        {
            Flush();
        }

        public void Flush()
        {
            var enumerator = new Enumerator(this);
            while (enumerator.MoveNext())
            {
                if (!enumerator.Current.IsAlive)
                {
                    enumerator.RemoveCurrent();
                }
            }
        }

        protected override Entry NewEntry(TKey key, TValue value)
        {
            return new WeakKeyHashMapEntry(key, value);
        }
    }
}